package com.powerbank.user.service.impl;

import com.powerbank.user.service.DeviceCommunicationService;
import com.powerbank.user.vo.DeviceStatusVO;
import com.powerbank.user.vo.SlotStatusVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClientException;

import java.time.LocalDateTime;
import java.util.Random;

/**
 * 设备通信服务实现类
 * 集成真实的设备服务API和模拟功能
 */
@Slf4j
@Service
public class DeviceCommunicationServiceImpl implements DeviceCommunicationService {

    private final Random random = new Random();
    private final RestTemplate restTemplate = new RestTemplate();
    
    @Value("${device-service.url:http://localhost:8083/device-service}")
    private String deviceServiceUrl;

    @Override
    public boolean sendUnlockCommand(String deviceCode, Integer slotNo) {
        log.info("发送开锁指令到设备: {}, 插槽: {}", deviceCode, slotNo);
        
        try {
            // 调用设备服务API
            String url = deviceServiceUrl + "/device/unlock/" + deviceCode + "/" + slotNo;
            String response = restTemplate.postForObject(url, null, String.class);
            
            if (response != null && response.contains("指令发送成功")) {
                log.info("设备{}插槽{}开锁指令发送成功", deviceCode, slotNo);
                return true;
            } else {
                log.warn("设备{}插槽{}开锁指令发送失败: {}", deviceCode, slotNo, response);
                return false;
            }
        } catch (RestClientException e) {
            log.error("调用设备服务开锁接口失败", e);
            // 降级到模拟实现
            return simulateUnlockCommand(deviceCode, slotNo);
        } catch (Exception e) {
            log.error("发送开锁指令时发生异常", e);
            return false;
        }
    }
    
    /**
     * 模拟开锁指令（降级方案）
     */
    private boolean simulateUnlockCommand(String deviceCode, Integer slotNo) {
        try {
            Thread.sleep(200);
            boolean success = random.nextDouble() < 0.95;
            
            if (success) {
                log.info("设备{}插槽{}开锁成功（模拟）", deviceCode, slotNo);
            } else {
                log.warn("设备{}插槽{}开锁失败（模拟）", deviceCode, slotNo);
            }
            
            return success;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    public boolean sendLockCommand(String deviceCode, Integer slotNo) {
        log.info("发送锁定指令到设备: {}, 插槽: {}", deviceCode, slotNo);
        
        try {
            // 调用设备服务API
            String url = deviceServiceUrl + "/device/lock/" + deviceCode + "/" + slotNo;
            String response = restTemplate.postForObject(url, null, String.class);
            
            if (response != null && response.contains("指令发送成功")) {
                log.info("设备{}插槽{}锁定指令发送成功", deviceCode, slotNo);
                return true;
            } else {
                log.warn("设备{}插槽{}锁定指令发送失败: {}", deviceCode, slotNo, response);
                return false;
            }
        } catch (RestClientException e) {
            log.error("调用设备服务锁定接口失败", e);
            // 降级到模拟实现
            return simulateLockCommand(deviceCode, slotNo);
        } catch (Exception e) {
            log.error("发送锁定指令时发生异常", e);
            return false;
        }
    }
    
    /**
     * 模拟锁定指令（降级方案）
     */
    private boolean simulateLockCommand(String deviceCode, Integer slotNo) {
        try {
            Thread.sleep(200);
            boolean success = random.nextDouble() < 0.98;
            
            if (success) {
                log.info("设备{}插槽{}锁定成功（模拟）", deviceCode, slotNo);
            } else {
                log.warn("设备{}插槽{}锁定失败（模拟）", deviceCode, slotNo);
            }
            
            return success;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    public DeviceStatusVO queryDeviceStatus(String deviceCode) {
        log.info("查询设备状态: {}", deviceCode);
        
        // 模拟查询设备状态
        DeviceStatusVO status = new DeviceStatusVO();
        status.setDeviceCode(deviceCode);
        status.setOnlineStatus(1); // 在线
        status.setDeviceStatus(1); // 正常
        status.setTotalSlots(6);
        status.setAvailableSlots(random.nextInt(4) + 1); // 1-4个可用插槽
        status.setOccupiedSlots(status.getTotalSlots() - status.getAvailableSlots());
        status.setBatteryLevel(random.nextInt(40) + 60); // 60-100%电量
        status.setSignalStrength(random.nextInt(30) + 70); // 70-100%信号强度
        status.setLastHeartbeatTime(LocalDateTime.now().minusSeconds(random.nextInt(30)));
        status.setStatusDesc("设备运行正常");
        
        return status;
    }

    @Override
    public SlotStatusVO querySlotStatus(String deviceCode, Integer slotNo) {
        log.info("查询插槽状态: {}, 插槽: {}", deviceCode, slotNo);
        
        // 模拟查询插槽状态
        SlotStatusVO status = new SlotStatusVO();
        status.setDeviceCode(deviceCode);
        status.setSlotNo(slotNo);
        status.setSlotStatus(random.nextBoolean() ? 0 : 1); // 随机空闲或占用
        
        if (status.getSlotStatus() == 1) {
            status.setPowerbankId(random.nextLong(1000000) + 1000000L);
            status.setBatteryLevel(random.nextInt(100) + 1);
        }
        
        status.setLockStatus(status.getSlotStatus()); // 占用时锁定
        status.setLastUpdateTime(LocalDateTime.now());
        status.setStatusDesc(status.getSlotStatus() == 0 ? "空闲" : "已占用");
        
        return status;
    }

    @Override
    public Integer getDeviceBatteryLevel(String deviceCode) {
        log.info("获取设备电量: {}", deviceCode);
        
        // 模拟获取设备电量
        return random.nextInt(40) + 60; // 60-100%
    }
}